part of 'card.dart';

class _AudioCardWloc extends StatefulWloc<_AudioCardWlocState, AudioCard>
    with TickerProviderStateMixin, CardWlocMixin {
  late final bloc.AudioCardBloc _bloc;

  late final TextEditingController textEditingController;
  late final AnimationController correctAnswerColorAnimationController;
  late final AnimationController wrongAnswerShakeAnimationController;

  @override
  _AudioCardWlocState get initialState {
    final finished = _isFinished(
      blocState: _bloc.state,
    );

    return _AudioCardWlocState(
      lexicalItem: widget.lexicalItem,
      dialect: widget.dialect,
      safeToPronounce: widget.safeToPronounce,
      autoPronunciationEnabled: widget.autoPronunciationEnabled,
      finished: finished,
    );
  }

  bool _isFinished({
    required bloc.AudioCardBlocState blocState,
  }) {
    return blocState.exerciseSucceeded || blocState.exerciseFailed;
  }

  void onPronunciationCautionButtonPressed() {
    showPronunciationCautionDialog(
      context: context,
    );
  }

  void onLexicalItemPronunciationButtonPressed() {
    _bloc.requestLexicalItemPronunciation();
  }

  void onHintButtonPressed() {
    widget.onHintUsed();
    _bloc.requestHintApplying();
  }

  void _onTextChanged() {
    _bloc.requestInputTextChange(
      inputText: textEditingController.text,
    );
  }

  void _onBlocStateChanged(bloc.AudioCardBlocState blocState) {
    final finished = _isFinished(
      blocState: blocState,
    );

    final updatedState = state.copyWith(
      finished: () => finished,
    );

    emit(updatedState);

    if (textEditingController.text != blocState.inputText) {
      textEditingController.text = blocState.inputText;
    }

    if (blocState.exerciseSucceeded) {
      correctAnswerColorAnimationController.forward().whenComplete(widget.onSucceeded);
    } else if (blocState.exerciseFailed) {
      wrongAnswerShakeAnimationController.forward().whenComplete(widget.onFailed);
    }
  }

  @override
  void initState() {
    super.initState();

    _bloc = bloc.AudioCardBloc(
      lexicalItem: widget.lexicalItem,
       getInitialData: audio_card_di.sl(),
       applyHint: audio_card_di.sl(),
       handleInputTextOuterUpdate: audio_card_di.sl(),
       pronounceLexicalItem: audio_card_di.sl(),
    );

    _bloc.stream.listen(_onBlocStateChanged);

    textEditingController = TextEditingController(
      text: _bloc.state.inputText,
    );

    textEditingController.addListener(_onTextChanged);

    correctAnswerColorAnimationController = AnimationController(
      vsync: this,
      duration: kCardCorrectAnswerColorAnimationDuration,
    );

    wrongAnswerShakeAnimationController = AnimationController(
      vsync: this,
      duration: kShakeAnimationDuration,
    );
  }

  @override
  void didUpdateWidget(AudioCard oldWidget) {
    super.didUpdateWidget(oldWidget);

    final updatedState = state.copyWith(
      dialect: () => widget.dialect,
      safeToPronounce: () => widget.safeToPronounce,
      autoPronunciationEnabled: () => widget.autoPronunciationEnabled,
    );

    emit(updatedState);
  }

  @override
  void dispose() {
    _bloc.close();
    textEditingController.dispose();
    correctAnswerColorAnimationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _AudioCardView(
      wloc: this,
    );
  }
}
